
package SSF.Util.Streams;

import com.renesys.raceway.DML.*;
import java.io.*;

public class StreamField {

    public static final int FIELD_INVALID = 0x0;
    public static final int FIELD_INT32   = 0x1;
    public static final int FIELD_FLT32   = 0x2;
    public static final int FIELD_INT64   = 0x3;
    public static final int FIELD_FLT64   = 0x4;

    String fieldID;
    int fieldType;

    private StreamField() {};

    public static StreamField make(Configuration cfg) {
	try {
	    StreamField sf = new StreamField();
	    sf.config(cfg);
	    return sf;
	} catch (configException cex) {
	    return null;
	}
    }

    //----------------------------------------------------------------------
    // CONFIG

    /** Syntax: field [id XX type YY] where YY={int32,int64,flt32,flt64}. 
     */
    public void config(Configuration cfg) throws configException {
	if (null == (fieldID = (String)cfg.findSingle("id")))
	    throw new configException("Missing field.id attribute");
				      
	String ftype = (String)cfg.findSingle("type");
	init(fieldID,ftype);
	if (FIELD_INVALID == fieldType) 
	    throw new configException((null==ftype?"Missing":"Invalid")+
				      " field.type attribute");
    }

    protected void init(String fieldID, String fieldType) {
	this.fieldID = fieldID;
	this.fieldType = FIELD_INVALID;
	if ("int32".equals(fieldType)) this.fieldType=FIELD_INT32;
	if ("int64".equals(fieldType)) this.fieldType=FIELD_INT64;
	if ("flt32".equals(fieldType)) this.fieldType=FIELD_FLT32;
	if ("flt64".equals(fieldType)) this.fieldType=FIELD_FLT64;
    }

    //----------------------------------------------------------------------
    // ACCESSING CONTENT 

    public double doubleValue(DataInputStream bin) throws IOException {
	switch(fieldType) {
	case FIELD_INT32:
	    return bin.readInt();
	case FIELD_INT64:
	    return bin.readLong();
	case FIELD_FLT32:
	    return bin.readFloat();
	case FIELD_FLT64:
	    return bin.readDouble();
	default:
	    System.err.println
		("StreamField.doubleValue(): invalid field type?");
	    return Double.MIN_VALUE;
	}
    }

    public float floatValue(DataInputStream bin) throws IOException {
	switch(fieldType) {
	case FIELD_INT32:
	    return bin.readInt();
	case FIELD_INT64:
	    return bin.readLong();
	case FIELD_FLT32:
	    return bin.readFloat();
	case FIELD_FLT64:
	    return (float)bin.readDouble();
	default:
	    System.err.println
		("StreamField.floatValue(): invalid field type?");
	    return Float.MIN_VALUE;
	}
    }

    public int intValue(DataInputStream bin) throws IOException {
	switch(fieldType) {
	case FIELD_INT32:
	    return bin.readInt();
	case FIELD_INT64:
	    return (int)bin.readLong();
	case FIELD_FLT32:
	    return (int)bin.readFloat();
	case FIELD_FLT64:
	    return (int)bin.readDouble();
	default:
	    System.err.println("StreamField.intValue(): invalid field type?");
	    return Integer.MIN_VALUE;
	}
    }

    public long longValue(DataInputStream bin) throws IOException {
	switch(fieldType) {
	case FIELD_INT32:
	    return bin.readInt();
	case FIELD_INT64:
	    return bin.readLong();
	case FIELD_FLT32:
	    return (long)bin.readFloat();
	case FIELD_FLT64:
	    return (long)bin.readDouble();
	default:
	    System.err.println("StreamField.longValue(): invalid field type?");
	    return Long.MIN_VALUE;
	}
    }
}
